package com.itheima.adviser;

import com.itheima.Metric;
import com.itheima.service.AccountService;
import sun.rmi.runtime.Log;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;

/**
 * @ClassName: PerformanceAdviser
 * @Description:
 * @Author liulihui          jdk动态代理有要求,必须有接口类.
 * InvocationHandler的实现类就是专门来写业务逻辑的,增强业务逻辑.所有的内容都在这里写
 * @Date: 2021/7/30 16:23
 * @URL：
 * @Version 1.0
 */
public class PerformanceAdviser implements InvocationHandler {

    private AccountService ori;

    public PerformanceAdviser(AccountService ori) {
        this.ori = ori;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //判断一哈,正要执行的方法是否存在注解标识   利用动态代理技术和注解技术实现精确加强

        //获取ori对象所对应得方法   利用反射获取ori对象的method方法,实现类的方法签名和它实现的接口的签名一致,即参数,返回值,方法名一致.
        Method methodimpl= ori.getClass().getMethod(method.getName(), method.getParameterTypes());
  //注解也是类,接口也是类其实
        Object result=null;  //任何时候不管下面用哪个方法,我们都先定义一个返回值为null
       if(methodimpl.isAnnotationPresent(Metric.class)){
           //你有这个注解,我就加强你的逻辑
           System.out.println("增强业务逻辑开始");
           long start= System.currentTimeMillis();
        /*其次method是接口中的方法，当实现类只是要调用invoke方法的时候是不区分的这个method是声明在接口的还是是原来的是实现类的，只有当要用到
        这个实现类上的注解或者类上的具体参数时才用区别开来*/
           result = method.invoke(ori, args);
           long end = System.currentTimeMillis();
           System.out.println("总共花费了"+(end-start)+"毫秒");

       }else{
           //没有注解就不加强,执行原来的逻辑就行.不做任何加强
           result = method.invoke(ori, args);
       }
        return result;
    }
}